package boundary;

import java.awt.GridBagLayout;
import javax.swing.DefaultListModel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JPopupMenu;
import java.awt.GridBagConstraints;
import java.awt.Font;
import javax.swing.JList;
import javax.swing.JButton;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import dataview.Cibi;
import dataview.Portate;
import dataview.Ricette;
import exceptions.DBException;
import store.BaseStore;
import store.Cibo;
import store.Menu;
import store.Portata;
import store.Termine;
import store.TutteRicette;
import store.TuttiCibi;
import store.TuttiMenu;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JScrollPane;
import javax.swing.ImageIcon;
import java.awt.event.KeyEvent;
import javax.swing.BorderFactory;
import javax.swing.border.BevelBorder;
import java.awt.Dimension;

public class ListaPortate extends JPanel implements ActionListener {
	public static enum TipoDato {
		RICETTE, CIBI, BEVANDE
	};
	
	private static final long serialVersionUID = 1L;
	private Menu menu; //  @jve:decl-index=0:
	private Home home;
	private Portate portate; //  @jve:decl-index=0:
	private JPopupMenu pmMenu; //  @jve:decl-index=0:
	private Ricette ricette;
	private Cibi cibi, bevande;
	private JMenuItem ricetta, cibo, bevanda;
	private JLabel jLabel = null;
	private JList jList = null;
	private DefaultListModel model = null;
	private JButton bAggiungi = null;
	private JButton bElimina = null;
	private JButton bModifica = null;
	private JButton bConferma = null;
	
	private boolean modifica;
	private JScrollPane jScrollPane = null;
	
	/**
	 * This is the default constructor
	 */
	public ListaPortate(Home home, Menu menu) {
		super();
		this.home = home;
		this.menu = menu;
		try {
			ricette = TutteRicette.getTutteRicette().tutteRicette();
			cibi = new Cibi();
			for (Cibo c : TuttiCibi.getTuttiCibi().tuttiCibi()) {
				if (!(c.getTag().getFirst().diTipo(Termine.bevanda))) cibi.add(c);
			}
			bevande = new Cibi();
			for (Cibo c : TuttiCibi.getTuttiCibi().tuttiCibi()) {
				if ((c.getTag().getFirst().diTipo(Termine.bevanda))) bevande.add(c);
			}
		} catch (DBException e) {
			e.printStackTrace();
		}
		modifica = !menu.getPortate().isEmpty();
		initialize();
	}
	
	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
		gridBagConstraints3.fill = GridBagConstraints.BOTH;
		gridBagConstraints3.weighty = 1.0;
		gridBagConstraints3.gridx = 0;
		gridBagConstraints3.gridy = 1;
		gridBagConstraints3.gridwidth = 4;
		gridBagConstraints3.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints3.weightx = 1.0;
		GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
		gridBagConstraints5.gridx = 3;
		gridBagConstraints5.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints5.anchor = GridBagConstraints.WEST;
		gridBagConstraints5.gridy = 2;
		GridBagConstraints gridBagConstraints21 = new GridBagConstraints();
		gridBagConstraints21.gridx = 2;
		gridBagConstraints21.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints21.anchor = GridBagConstraints.WEST;
		gridBagConstraints21.gridy = 2;
		GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
		gridBagConstraints11.gridx = 1;
		gridBagConstraints11.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints11.anchor = GridBagConstraints.WEST;
		gridBagConstraints11.gridy = 2;
		GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
		gridBagConstraints2.gridx = 0;
		gridBagConstraints2.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints2.anchor = GridBagConstraints.WEST;
		gridBagConstraints2.gridy = 2;
		GridBagConstraints gridBagConstraints = new GridBagConstraints();
		gridBagConstraints.gridx = 0;
		gridBagConstraints.gridwidth = 4;
		gridBagConstraints.insets = new Insets(5, 5, 5, 5);
		gridBagConstraints.gridy = 0;
		jLabel = new JLabel();
		jLabel.setText("Elenco portate del menu \"" + menu + "\"");
		jLabel.setFont(new Font("Dialog", Font.BOLD, 20));
		this.setSize(464, 219);
		this.setLayout(new GridBagLayout());
		this.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
		this.add(jLabel, gridBagConstraints);
		this.add(getJScrollPane(), gridBagConstraints3);
		this.add(getBAggiungi(), gridBagConstraints2);
		this.add(getBElimina(), gridBagConstraints11);
		this.add(getBModifica(), gridBagConstraints21);
		this.add(getBConferma(), gridBagConstraints5);
		this.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				if (pmMenu != null && pmMenu.isVisible()) pmMenu.setVisible(false);
			}
		});
	}
	
	/**
	 * This method initializes jList
	 * 
	 * @return javax.swing.JList
	 */
	private JList getJList() {
		if (jList == null) {
			updateModel();
			jList = new JList(model);
			jList.addListSelectionListener(new ListSelectionListener() {
				
				@Override
				public void valueChanged(ListSelectionEvent e) {
					bModifica.setEnabled(jList.getSelectedIndex() >= 0);
					bElimina.setEnabled(jList.getSelectedIndex() >= 0);
				}
			});
		}
		return jList;
	}
	
	private void updateModel() {
		model = new DefaultListModel();
		if (menu.getPortate() == null)
			portate = new Portate();
		else portate = menu.getPortate();
		for (Portata p : portate) {
			model.addElement(p);
		}
		getBConferma().setEnabled(!menu.getPortate().isEmpty());
	}
	
	/**
	 * This method initializes jButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getBAggiungi() {
		if (bAggiungi == null) {
			bAggiungi = new JButton();
			bAggiungi.setText("Aggiungi");
			bAggiungi.setActionCommand("Aggiungi");
			bAggiungi.setIcon(new ImageIcon(getClass().getResource("/icone/add-icon.png")));
			bAggiungi.addActionListener(this);
			bAggiungi.setFont(new Font("Dialog", Font.BOLD, 12));
		}
		return bAggiungi;
	}
	
	/**
	 * This method initializes jButton1
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getBElimina() {
		if (bElimina == null) {
			bElimina = new JButton();
			bElimina.setText("Elimina");
			bElimina.setEnabled(false);
			bElimina.setIcon(new ImageIcon(getClass().getResource("/icone/remove-icon.png")));
			bElimina.setActionCommand("Elimina");
			bElimina.addActionListener(this);
			bElimina.setFont(new Font("Dialog", Font.BOLD, 12));
		}
		return bElimina;
	}
	
	/**
	 * This method initializes jButton2
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getBModifica() {
		if (bModifica == null) {
			bModifica = new JButton();
			bModifica.setText("Modifica");
			bModifica.setIcon(new ImageIcon(getClass().getResource("/icone/comment-edit-icon.png")));
			bModifica.setEnabled(false);
			bModifica.setMnemonic(KeyEvent.VK_UNDEFINED);
			bModifica.addActionListener(this);
			bModifica.setFont(new Font("Dialog", Font.BOLD, 12));
		}
		return bModifica;
	}
	
	/**
	 * This method initializes jButton3
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getBConferma() {
		if (bConferma == null) {
			bConferma = new JButton();
			bConferma.setText("Conferma");
			bConferma.setIcon(new ImageIcon(getClass().getResource("/icone/accept-icon.png")));
			bConferma.addActionListener(this);
			bConferma.setEnabled(!menu.getPortate().isEmpty());
			bConferma.setFont(new Font("Dialog", Font.BOLD, 12));
		}
		return bConferma;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		InserisciUnaPortata ip;
		TipoDato td;
		if (e.getSource() == getBAggiungi()) {
			if (pmMenu == null) {
				pmMenu = new JPopupMenu();
				ricetta = new JMenuItem("Aggiungi una ricetta al menu");
				ricetta.setEnabled(ricette.size() > 0);
				cibo = new JMenuItem("Aggiungi un cibo al menu");
				cibo.setEnabled(cibi.size() > 0);
				bevanda = new JMenuItem("Aggiungi una bevanda al menu");
				bevanda.setEnabled(bevande.size() > 0);
				ricetta.addActionListener(this);
				cibo.addActionListener(this);
				bevanda.addActionListener(this);
				pmMenu.add(ricetta);
				pmMenu.add(cibo);
				pmMenu.add(bevanda);
				pmMenu.setEnabled(true);
			}
			pmMenu.setVisible(true);
			pmMenu.setVisible(false);
			pmMenu.show(getBAggiungi(), 0, (int)-pmMenu.getSize().getHeight());
		} else if (e.getSource() == getBElimina()) {
			Portata p = menu.getPortate().get(jList.getSelectedIndex());
			int res = JOptionPane.showConfirmDialog(this, "Sicuro di voler eliminare questa portata?", "Conferma eliminazione", JOptionPane.OK_CANCEL_OPTION);
			if (res == JOptionPane.OK_OPTION) {
				menu.eliminaPortata(p);
				updateModel();
				jList.setModel(model);
			}
		} else if (e.getSource() == getBModifica()) {
			ip = new InserisciUnaPortata(home, this, getJList().getSelectedIndex(), (Portata)jList.getSelectedValue());
			ip.setVisible(true);
		} else if (e.getSource() == getBConferma()) {
			if (BaseStore.isModificato(menu)) {
				int res;
				if (!modifica)
					res = JOptionPane.showConfirmDialog(this, "Sicuro di voler inserire questo menu?", "Conferma inserimento", JOptionPane.OK_CANCEL_OPTION);
				else res = JOptionPane.showConfirmDialog(this, "Sicuro di voler modificare questo menu?", "Conferma modifica", JOptionPane.OK_CANCEL_OPTION);
				if (res == JOptionPane.OK_OPTION) {
					if (!modifica) {
						try {
							TuttiMenu.getTuttiMenu().inserire(menu);
							JOptionPane.showMessageDialog(this, "Menu \"" + menu.getNome() + "\" inserito correttamente", "Menu inserito", JOptionPane.INFORMATION_MESSAGE);
						} catch (Exception e1) {
							e1.printStackTrace();
							JOptionPane.showMessageDialog(this, "Spiacente, impossibile inserire, database non funzionante", "Errore", JOptionPane.ERROR_MESSAGE);
						}
					} else {
						try {
							if (BaseStore.salvaModifiche(menu))
								JOptionPane.showMessageDialog(this, "Menu \"" + menu.getNome() + "\" modificato correttamente", "Menu modificato", JOptionPane.INFORMATION_MESSAGE);
						} catch (DBException e1) {
							e1.printStackTrace();
							JOptionPane.showMessageDialog(this, "Spiacente, impossibile modificare, database non funzionante", "Errore", JOptionPane.ERROR_MESSAGE);
						}
					}
					home.mostraListaMenu(null);
				}
			} else home.mostraListaMenu(null);
		} else { // per forza un jmenuitem del popup
			if (model.size() > 0 && jList.getSelectedIndex() < 0) {
				JOptionPane.showMessageDialog(this, "Selezionare prima una portata per scegliere la posizione in cui inserire la nuova portata", "Attenzione", JOptionPane.WARNING_MESSAGE);
				return;
			}
			int posiz = jList.getSelectedIndex() == -1 ? 0 : jList.getSelectedIndex();
			if (e.getSource() == ricetta)
				td = TipoDato.RICETTE;
			else if (e.getSource() == cibo)
				td = TipoDato.CIBI;
			else td = TipoDato.BEVANDE;
			if (model.size() > 0) {
				String[] options = { "Prima", "Dopo" };
				int choose = JOptionPane.showOptionDialog(this, "Inserire prima o dopo la portata selezionata?", "Scegli posizione portata", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
				System.err.println(choose);
				if (choose == -1) return;
				if (choose == 1) // prima
					++posiz;
			}
			ip = new InserisciUnaPortata(home, this, posiz, td);
			ip.setVisible(true);
		}
	}
	
	public void portataInserita(Portata portata, int pos, boolean modifica) {
		if (modifica) {
			menu.eliminaPortata(menu.getPortate().get(pos));
		}
		menu.aggiungiPortata(portata, pos);
		updateModel();
		getJList().setModel(model);
	}

	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane() {
		if (jScrollPane == null) {
			jScrollPane = new JScrollPane();
			jScrollPane.setViewportView(getJList());
		}
		return jScrollPane;
	}
} //  @jve:decl-index=0:visual-constraint="10,10"